#include "UdpClient.hpp"
UdpClient::UdpClient(TcpSocketDataInfo *pTcpSocketDataInfo):do_recv(true),pTcpSocketDataInfo(pTcpSocketDataInfo) {
    createSocket();
}

void UdpClient::createSocket() {
    struct addrinfo hints, * res;
    int status;
    //clear hints
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_flags = AI_PASSIVE;

    status = getaddrinfo("192.168.10.16","4673", &hints, &pAddrinfo);
    if(status != 0)
    {
        fprintf(stderr, "Error getaddrinfo\n");
        exit(1);
    }       
    
    socket_id = socket(pAddrinfo->ai_family, pAddrinfo->ai_socktype, pAddrinfo->ai_protocol);
    if(socket_id < 0)
    {
        fprintf(stderr, "Error socket \n");
        exit(2);
    }
	
    


}
extern "C" void udpSocketRecv ( void * pParam )
{
	UdpClient *client = reinterpret_cast < UdpClient * > ( pParam );
	char buffer[1024];
	int size = 1024;
	TcpSocketDataInfo *pTcpSocketDataInfo = client->pTcpSocketDataInfo;
	
	    int numbytes = 0;
		while(client->do_recv) {
			numbytes = recv(client->socket_id,buffer,size, 0);
			printf("Received data length is %d\n", numbytes);
		    if(numbytes == -1)
		    {
		        fprintf(stderr, "Error receive \n");
		        exit(4);
		    } else if(numbytes > 0){
		        
			epicsMutexLock(pTcpSocketDataInfo->mutex);
			int nUsed = epicsRingBytesUsedBytes(pTcpSocketDataInfo->ring);
			//printf("recieve thread ring[%ld] -- nUsed is %d\n",pTcpSocketDataInfo->ring, nUsed);
			
			epicsRingBytesPut(pTcpSocketDataInfo->ring, (char *)buffer, numbytes);
			nUsed = epicsRingBytesUsedBytes(pTcpSocketDataInfo->ring);
			//printf("epicsRingBytesPut after nUsed is %dpTcpSocketDataInfo->ring is %d\n", nUsed, pTcpSocketDataInfo->ring);
			epicsMutexUnlock(pTcpSocketDataInfo->mutex);
    
		    }
			
		}
	
}

void UdpClient::start() {
	int status;
	if(socket_id >= 0) {
		    status = connect(socket_id, pAddrinfo->ai_addr, pAddrinfo->ai_addrlen);
		    if(status < 0)
		    {
		        fprintf(stderr, "Error connect \n");
		        exit(3);
		    }
		}
	epicsThreadSleep(0.1);
	epicsThreadCreate ( 
        "client circuit", epicsThreadPriorityMedium, 
        epicsThreadGetStackSize(epicsThreadStackMedium), 
        udpSocketRecv, this );
	epicsThreadSleep(0.1);
	DataRingConsumeThread *runnable = new DataRingConsumeThread(pTcpSocketDataInfo);
	pDataRingConsumeThread = new epicsThread(*runnable, "DataRingConsumeThread", epicsThreadGetStackSize(epicsThreadStackMedium));
	pDataRingConsumeThread->start();
}


void UdpClient::close() {
		
		
	}
int UdpClient::receive(unsigned char *buffer, int size) {

}

